package com.platform.qujia.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.Maps;
import com.platform.qujia.constantEnum.Constant;
import com.platform.qujia.constantEnum.DecimalConstant;
import com.platform.qujia.controller.QuJiaPayV2Controller;
import com.platform.qujia.dao.*;
import com.platform.qujia.enums.PayTypeEnum;
import com.platform.qujia.enums.PayWayServiceChargeEnum;
import com.platform.qujia.enums.PayWayUseTypeEnum;
import com.platform.qujia.handle.PayOrderHandle;
import com.platform.qujia.param.request.AddPayOrderParam;
import com.platform.qujia.param.request.BankCardUpdateOrderParam;
import com.platform.qujia.param.request.PayOrderRequest;
import com.platform.qujia.pojo.*;
import com.platform.qujia.pojo.dto.ReductionAndCouponDTO;
import com.platform.qujia.pojo.vo.CouponUserCountVO;
import com.platform.qujia.pojo.vo.POSPayOrderVO;
import com.platform.qujia.service.AppUserInfoService;
import com.platform.qujia.service.OrderPayTypeService;
import com.platform.qujia.service.PayOrderService;
import com.platform.qujia.service.ReductionActivityService;
import com.platform.qujia.utils.LocalDateTimeUtil;
import com.platform.qujia.utils.MobilePhoneUtil;
import com.platform.qujia.utils.ResultData;
import com.platform.qujia.utils.StringUtils;
import com.platform.qujia.utils.exception.CustomException;
import com.yunhua.oil.common.core.utils.LocalDateUtils;
import com.yunhua.oil.common.core.utils.SpringUtils;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

@Service("payOrderService")
public class PayOrderServiceImpl implements PayOrderService {

	private static Logger logger =(Logger) LoggerFactory.getLogger(PayOrderServiceImpl.class);
	
    @Resource
    private PayOrderMapper payOrderMapper;

    @Resource
    private CouponMapper couponMapper;

    @Resource
    private StaOilGunMapper staOilGunMapper;
    @Autowired
    private StationMapper stationMapper;
    @Autowired
    private ReductionActivityMapper reductionActivityMapper;
    @Autowired
    private ReductionRulesMapper reductionRulesMapper;
    @Autowired
    private PayWayMapper payWayMapper;
    @Autowired
    private InvoiceMapper invoiceMapper;
    @Autowired
    private ReductionActivityService reductionActivityService;

    @Autowired
    private PayOrderHistoryMapper payOrderHistoryMapper;
    @Autowired
    private AppUserInfoService appUserInfoService;
    @Lazy
    @Autowired
    private QuJiaPayV2Controller quJiaPayV2Controller;
    @Autowired
    private OrderPayTypeService orderPayTypeService;
    @Value("${spring.profiles.active}")
    private String profile;

    
    /**
     * 行业id
     */
	@Value("${tianQuetechIndustryId}")
	public String tianQuetechIndustryId;
	
	/**
	 * 产品id
	 */
	@Value("${tianQuetechProductId}")
	public String tianQuetechProductId;
    

    @Override
    public List<PayOrder> posSelectAppCashPayOrdersList(PayOrder payOrder) {
        return payOrderMapper.posSelectAppCashPayOrdersList(payOrder);
    }

    //根据订单号查询订单
    @Override
    public PayOrder selectOrderInfoByOrdNo(String orderNo) {
        return payOrderMapper.selectOrderInfoByOrdNo(orderNo);
    }

    //cherkCouponCount
    @Override
    public Map<String, Object> cherkCouponCount(PayOrderRequest request) {
        Map<String, Object>  a  = new HashMap<>();
        a.put("status","1");

        String couponUserId =  request.getCouponUserId();
        String mobilePhone = request.getMobilePhone();
        if(couponUserId==null||mobilePhone==null){
            a.put("status","1");
             return a;
        }
        CouponUserCountVO couponId = payOrderMapper.selectByCouponNoPhoneByUserCouponId(couponUserId,mobilePhone);
        if( couponId.getCouponActivityId()==null){
            a.put("status","1");
            return a;
        }else if(couponId.getCouponActivityId()!=null){
            Map<String,Object> nff =   couponMapper.getActivityAllByActivityId(couponId.getCouponActivityId());
            if(nff==null){
                a.put("status","1");
                return a;
            }
        }
       String couponNo =  couponId.getCouponDayAndMoon();
        List<CouponUserCountVO>  countDay =    payOrderMapper.selectByCouponNoPhoneAllCount(couponNo,mobilePhone);
        Integer activityDayCount = null;
        for(CouponUserCountVO countD :countDay){
            String couponActivityId =   countD.getCouponActivityId();
            String couponType=   countD.getCouponType();
                BigDecimal  couponAmt = countD.getCouponAmt();
            Map<String, Object> objectMap = new HashMap<>();
            objectMap.put("couponActivityId",couponActivityId);
            objectMap.put("couponAmt",couponAmt);
            objectMap.put("couponType",couponType);
            CouponUserCountVO   couponDayCountVO =  payOrderMapper.selectCounponActivityCount(objectMap);
          if(couponDayCountVO!=null){
              if(activityDayCount == null){
                  if (couponDayCountVO.getCouponCount()==null){
                      activityDayCount = 0 +  999999999;
                  }else{
                      activityDayCount = 0 +  couponDayCountVO.getCouponCount();

                  }
              }else{
                  if (couponDayCountVO.getCouponCount()==null){
                      activityDayCount = 0 +  999999999;
                  }else{
                      activityDayCount = activityDayCount + couponDayCountVO.getCouponCount();

                  }

              }

          }

        }

if(activityDayCount == null){
    a.put("status","1");
    return a;
}else{
    Integer userDayCount = 0;
    String couponType = countDay.get(0).getCouponType();
    BigDecimal couponAmt =   countDay.get(0).getCouponAmt();
    CouponUserCountVO  countDayVo =    payOrderMapper.selectByCouponNoPhoneDay(mobilePhone,couponType,couponAmt);
if(countDayVo!=null){
    userDayCount = countDayVo.getCouponCount();
    }
    if(activityDayCount>userDayCount){

    }else{
        a.put("status","2");
        a.put("msg","今日该优惠券面额使用次数超出使用限制");
        return a;
    }
}
        // 获取本月的第一天
        LocalDate firstDayOfMonth = LocalDate.now().withDayOfMonth(1);
        LocalDateTime startDateTime = LocalDateTime.of(firstDayOfMonth, LocalTime.MIN);
        String startDateTimeString = startDateTime.toString();

        // 获取本月的最后一天
        LocalDate lastDayOfMonth = LocalDate.now().withDayOfMonth(firstDayOfMonth.lengthOfMonth());
        LocalDateTime endDateTime = LocalDateTime.of(lastDayOfMonth, LocalTime.MAX);
        String endDateTimeString = endDateTime.toString();

        List<CouponUserCountVO>  countMoon =    payOrderMapper.selectByCouponNoPhoneAllCount(couponNo,mobilePhone);

        Integer activityMoonCount = null;

        for(CouponUserCountVO countM :countMoon){
            String couponActivityId =   countM.getCouponActivityId();
            String couponType=   countM.getCouponType();
            BigDecimal  couponAmt = countM.getCouponAmt();
            Map<String, Object> objectMap = new HashMap<>();
            objectMap.put("couponActivityId",couponActivityId);
            objectMap.put("couponAmt",couponAmt);
            objectMap.put("couponType",couponType);
            CouponUserCountVO   couponDayCountVO =  payOrderMapper.selectCounponActivityMoonCount(objectMap);
            if(couponDayCountVO!=null){
                if(activityMoonCount == null){
                    if (couponDayCountVO.getCouponCount()==null){
                        activityMoonCount = 0 +  999999999;
                    }else{
                        activityMoonCount = 0 +  couponDayCountVO.getCouponCount();

                    }

                }else{
                    if (couponDayCountVO.getCouponCount()==null){
                        activityMoonCount = 0 +  999999999;
                    }else{
                        activityMoonCount = activityMoonCount + couponDayCountVO.getCouponCount();

                    }

                }

            }

        }

        if(activityMoonCount == null){
            a.put("status","1");
            return a;
        }else{
            Integer userMoonCount = 0;
            String couponType = countDay.get(0).getCouponType();
            BigDecimal couponAmt =   countDay.get(0).getCouponAmt();
            CouponUserCountVO  countMoonVo =  payOrderMapper.selectByCouponNoPhoneMoon(couponType,couponAmt,mobilePhone,startDateTimeString,endDateTimeString);
            if(countMoonVo!=null){
                userMoonCount = countMoonVo.getCouponCount();
            }
            if(activityMoonCount>userMoonCount){

            }else{
                a.put("status","2");
                a.put("msg","本月该优惠券面额使用次数超出使用限制");
                return a;
            }
        }

        return a;
    }

    //根据商户订单号查询订单
    @Override
    public PayOrder selectOrderInfoByMerchantsNumber(String merchantsNumber) {
        return payOrderMapper.selectOrderInfoByMerchantsNumber(merchantsNumber);
    }

    //获取系统支付类型
    @Override
    public List<PayType> selectPayTypeList() {
        return payOrderMapper.selectPayTypeList();
    }
    //获取订单列表已转化汉字支付方式的
    @Override
    public List<PayOrder> selectPayOrderListFormater(PayOrder payOrder) {
        return payOrderMapper.selectPayOrderListFormater(payOrder);
    }

    //获取POS机昨天数据
    @Override
    public Map<String, Object> selectPosYesterDayData(PayOrder payOrder) {
        return payOrderMapper.selectPosYesterDayData(payOrder);
    }

    //查询POS机近七天数据
    @Override
    public List<Map<String, Object>> selectPosRecentlySevenData(PayOrder payOrder) {
        return payOrderMapper.selectPosRecentlySevenData(payOrder);
    }

    //查询订单信息
    @Override
    public List<PayOrder> getPayOrderList(String orderNo) {
        PayOrderExample example =new PayOrderExample();
        example.or().andOrderNoEqualTo(orderNo);
        return payOrderMapper.selectByExample(example);
    }

    //查询班结时间订单
    @Override
    public List<PayOrder> selectPayOrderList(PayOrder payOrder) {
        return payOrderMapper.selectPayOrderList(payOrder);
    }

    @Override
    public PayOrder getPayOrderInfoMin(PayOrder payOrder) {
        return payOrderMapper.getPayOrderInfoMin(payOrder);
    }

    @Override
    public PayOrder selectPosPayOrderInfoByOrderRandomId(String orderRandomId) {
        return payOrderMapper.selectPosPayOrderInfoByOrderRandomId(orderRandomId);
    }

    @Override
    public List<PayOrder> selectPosPayOrderListInfoByOrderRandomId(String orderRandomId) {
        return payOrderMapper.selectPosPayOrderListInfoByOrderRandomId(orderRandomId);
    }

    //LNG 平台第三方订单消费余额记录
    @Override
    public void insertStationBalanceExchange(StationBalanceChange stationBalanceChange){
        payOrderMapper.insertStationBalanceExchange(stationBalanceChange);
    }

    @Override
    public int selectUserOrderCount(Map<String, Object> param) {
        return payOrderMapper.selectUserOrderCount(param);
    }

    /**
     * 修改订单信息
     * @param payOrder
     */
    @Override
    public int getUpdatePayOrder(PayOrder payOrder) {
//        PayOrderExample example =new PayOrderExample();
//        example.or().andOrderIdEqualTo(payOrder.getOrderId());

        return payOrderMapper.getUpdatePayOrder(payOrder);
    }

    @Override
    public PayOrder searchPayOrder(Integer orderId) {
        PayOrder payOrder= payOrderMapper.selectByPrimaryKey(orderId);
        return payOrder;
    }

    //根据手机号查询用户信息
    @Override
    public List<AppUserInfo> getUserInfoByOpenId(AppUserInfo appUserInfo) {
        return payOrderMapper.getUserInfoByOpenId(appUserInfo);
    }

    /*
     * 根据用户openId和用户类型userType查询用户订单
     * @param payOrder
     * @return
     */
    @Override
    public List<PayOrder> getOrderListByOpenIdAndUserType(AppUserInfo appUserInfo) {
        return payOrderMapper.getOrderListByOpenIdAndUserType(appUserInfo);
    }

    /*
     * 根据用户unionId查询用户订单
     * @return
     */
    @Override
    public List<PayOrder> getUserOrderListByUnionId(AppUserInfo appUserInfo) {
        return payOrderMapper.getUserOrderListByUnionId(appUserInfo);
    }

    /*
     * 根据用户mobilePhone查询用户订单
     * @return
     */
    @Override
    public List<PayOrder> getUserOrderListByMobilePhone(AppUserInfo appUserInfo) {

        List<PayOrder> orderList = payOrderMapper.getUserOrderListByMobilePhone(appUserInfo);
        List<PayOrder> orderHistoryList = payOrderHistoryMapper.getUserOrderListByMobilePhone(appUserInfo);
        if(CollectionUtils.isEmpty(orderList)){
            return orderHistoryList;
        }
        if(CollectionUtils.isEmpty(orderHistoryList)){
            return orderList;
        }
        orderList.addAll(orderHistoryList);
        return orderList;
    }

    /*
     * 根据订单号查询订单信息和用户信息  注：此方法在随行付回调校验之后修改状态完成后
     * @param payOrder
     * @return
     */
    @Override
    public Map<String, Object> getOrderInfoAndUserInfoByOrderNo(PayOrder payOrder) {
        return payOrderMapper.getOrderInfoAndUserInfoByOrderNo(payOrder);
    }

    /*
     * 判断客户表是否已存在
     * @param customerManage
     * @return
     */
    @Override
    public CustomerManage isExistCustomer(CustomerManage customerManage) {
        return payOrderMapper.isExistCustomer(customerManage);
    }

    /*
     * 更新客户表 注：限用于随行付支付完成处
     * @param customerManage
     */
    @Override
    public void updateCustomer(CustomerManage customerManage) {
        payOrderMapper.updateCustomer(customerManage);
    }

    /*
     * 新增客户 注：限用于随行付支付完成处
     * @param customerManage
     */
    @Override
    public void insertCustomer(CustomerManage customerManage) {
        payOrderMapper.insertCustomer(customerManage);
    }

    /*
     *  根据手机号更新
     * @param customerManage
     */
    @Override
    public void updateCustomerByPhoneNumber(CustomerManage customerManage) {
        payOrderMapper.updateCustomerByPhoneNumber(customerManage);
    }

    //查询汇总数据
    public List<Map> selectSum(PayOrder payOrder){
        return  payOrderMapper.selectSum(payOrder);
    }

    public Map<String, Object> selectSumTmp(PayOrder payOrder){
        return  payOrderMapper.selectSumTmp(payOrder);
    };

    public int delOldRandomId(String orderRandomId){
        return payOrderMapper.delOldRandomId(orderRandomId);
    }

    @Override
    public List<POSPayOrderVO> selectPayOrderListTemp(PayOrder payOrder) {
        List<POSPayOrderVO> payOrders = payOrderMapper.selectPayOrderListTemp(payOrder);
        List<OrderPayType> orderPayTypes = orderPayTypeService.selectOrderPayType(Long.valueOf(payOrder.getStationId()));
        HashMap<String, String> typeMaps = Maps.newHashMapWithExpectedSize(orderPayTypes.size());
        for (OrderPayType orderPayType : orderPayTypes) {
            typeMaps.put(orderPayType.getPayType(),orderPayType.getPayTypeName());
        }
        for (POSPayOrderVO order : payOrders) {
            // 车队卡支付pay_order表里的consumer_id不是app_user_info表里的id，所以关联不到手机号
            // 判断手机号为空设置为pay_order表里的手机号
            if (org.apache.commons.lang3.StringUtils.isEmpty(order.getPayTypeName())) {
                String payTypeName = typeMaps.get(order.getPayType());
                if (org.apache.commons.lang3.StringUtils.isNotEmpty(payTypeName)) {
                    order.setPayTypeName(payTypeName);
                }
            }
            if (org.apache.commons.lang3.StringUtils.isEmpty(order.getMobilePhone())) {
                order.setMobilePhone(MobilePhoneUtil.encryPhone(order.getPayOrderCustomerPhone()));
            }
            order.setPayOrderCustomerPhone(null);
        }
        return payOrders;
    }
    
    @Override
    public PayOrder addPayOrder(AddPayOrderParam param,Integer appType) {
    	PayOrder newPayOrder = new PayOrder();             //生成订单参数
    	String orderNo=StringUtils.generateOrdNo();
//        Station station = enterpriseService.selectStationById(request.getStationId());
//        if(station == null){
//            throw new EndingException("未查询到油站");
//        }
    	//油品价格
        StaOilGun queryOilGun = new StaOilGun();
        queryOilGun.setGunName(param.getOilGun());    // 枪号
        queryOilGun.setStationId(param.getStationId());//油站id
        Station station = stationMapper.selectStationById(param.getStationId());
        StaOilGun staOilGun = staOilGunMapper.selectStaGunInfo(queryOilGun);
        if(staOilGun == null){
        	logger.info("创建订单失败，未找到油枪信息");
        	return null;
        }
//        PayWay payWay=new PayWay();
//        payWay.setMno(param.getMno());
//        payWay.setStationId(param.getStationId());
//        payWay.setPayType(PayWayPayTypeEnum.Pay_Type_Accompanying_payment.getValue().toString());
//        payWay.setPayType(param.getPayTypeEnum().getValue().toString());
//        PayWay ayWaydo=payWayMapper.selectServiceChargePayWayd(payWay);
//        if(ayWaydo==null) {
//        	logger.info("创建订单失败，未找到关联的支付渠道信息");
//        	return null;
//        }

        newPayOrder.setEnterpriseId(param.getEnterpriseId());
        newPayOrder.setEnterpriseName(station==null?null:station.getEnterprise().getEnterpriseName());
        newPayOrder.setAppType(param.getAppType());
        newPayOrder.setPayType(param.getPayType());
        newPayOrder.setOrderOriginType(param.getOrderOriginType());
        newPayOrder.setStationName(param.getStationName());
        newPayOrder.setOrderNo(orderNo);                                          //订单号
        newPayOrder.setStationId(param.getStationId());                  //油站id
        newPayOrder.setStatus("0");                                                //创建订单 未支付状态 0
        newPayOrder.setCreatedDate(new Timestamp(new Date().getTime()));           //创建时间
        newPayOrder.setOilGun(param.getOilGun());                        //油枪号
        newPayOrder.setReceivableAmt(Double.valueOf(param.getReceivableAmt()));      //订单应收金额
        newPayOrder.setDzkAmt(Double.valueOf(0));             //电子卡金额
        newPayOrder.setOilPirce(param.getOilPirce()); //油价 原价
        newPayOrder.setOrderType(staOilGun.getOil().getOilClass()); // 油品类
        newPayOrder.setOilName(staOilGun.getOilId().toString()); // 油品id
        newPayOrder.setAmt(Double.valueOf(param.getReceivableAmt())); //实收金额
        newPayOrder.setDiscountAmt(Double.valueOf("0.00")); //优惠金额
        newPayOrder.setOrderLiters(param.getOrderLiters()); // 油升数
        newPayOrder.setDiscountAmt(Double.valueOf("0.00"));
        newPayOrder.setOilPersonnelId(param.getOilPersonnelId());
//        newPayOrder.setPayWayId(ayWaydo.getPayWayId());
        // 订单来源默认9
        newPayOrder.setUtmSource("9");
        
        //现金支付的状态（0申请1取消）
        newPayOrder.setXJStatus("1");
        //实收金额
        newPayOrder.setAmt(Double.valueOf(param.getAmt()));
        //费率
        Map<String,Object> map=getServiceChargew(param.getStationId(),appType);
        BigDecimal serviceCharge=map.get("serviceCharge")==null?BigDecimal.ZERO:new BigDecimal(map.get("serviceCharge").toString());
        newPayOrder.setServiceCharge(serviceCharge);
        //渠道手续费支付方 0司机/1油企 channelFeePayer
        newPayOrder.setChannelFeePayer("1");
        //渠道费
        newPayOrder.setCommission(Double.valueOf("0.00"));
        PayOrderHandle.setPayOrderInvoiceStatus(newPayOrder);
        payOrderMapper.insertSelectiveOrder(newPayOrder);
    	return newPayOrder;
    }
    
    /**
     * 更新订单 settle_amt
     * @param orderSn		订单号
     * @param status		订单状态
     * @param serviceCharge	费率
     * @param commission	费额度
     * @param payDate		支付时间
     * @param receivedAmt	到账额度
     */
    @Override
    public int updateTradeReverseOrder(String orderSn,String status,BigDecimal serviceCharge,Double commission,Date payDate,Double receivedAmt) {
    	PayOrder payOrder=new PayOrder();
    	payOrder.setOrderNo(orderSn);
    	payOrder.setStatus(status);
    	payOrder.setServiceCharge(serviceCharge);
    	payOrder.setCommission(commission);
    	payOrder.setReceivedAmt(receivedAmt);
    	payOrderMapper.updateOrderPayDate(payDate, orderSn);
    	return payOrderMapper.updatePayOrder(payOrder);
    }

	@Override
	public int updateOrderPayDate(Date payDate, String orderNo) {
		return payOrderMapper.updateOrderPayDate(payDate, orderNo);
	}
    
	/**
	 * 使用油企id获取微信或者支付宝的费率
	 * @param stationId
	 * @param appType  应用渠道 1微信 2支付宝 3银行卡
	 * @return payWayServiceCharge
	 */
	public Map<String,Object> getServiceChargew(Integer stationId,Integer appType) {
		Map<String,Object> map=new HashMap<String, Object>();
		if(appType!=null) {
			map=payOrderMapper.selectServiceCharge(stationId,appType);
			return map==null?new HashMap<String, Object>():map;
		}
		map=payOrderMapper.selectServiceCharge(stationId,PayWayServiceChargeEnum.APPTYPE_WECHAT.getValue());
		if(map.get("serviceCharge")==null) {
			map=payOrderMapper.selectServiceCharge(stationId,PayWayServiceChargeEnum.APPTYPE_ALIPAY.getValue());
			}
		return map==null?new HashMap<String, Object>():map;
	}

	@Override
    @Transactional
	public String bankCardAddOrder(AddPayOrderParam param, Integer appType) {
        // 获取油枪、油品信息
        StaOilGun oilGun = getOilGun(param);

        AppUserInfo userInfo = null;
        if (StringUtils.isNotBlank(param.getConsumerId())) {
            String consumerId = param.getConsumerId();
            BigDecimal id = new BigDecimal(consumerId);
            userInfo = appUserInfoService.getById(id.intValue());
            if (userInfo == null) {
                throw new CustomException("会员未找到");
            }
        }

        //订单实付金额
        BigDecimal amt = new BigDecimal(param.getAmt());
        BigDecimal originalAmt = amt;
        PayOrder newPayOrder = new PayOrder();
        newPayOrder.setReceivableAmt(param.getReceivableAmt()); // 应收金额
        newPayOrder.setAmt(amt.doubleValue());// 实收金额
        newPayOrder.setDiscountAmt(0d);// 优惠金额
        newPayOrder.setConsumeDiscountAmt(BigDecimal.ZERO);
        newPayOrder.setRechargeDiscountAmt(BigDecimal.ZERO);
        newPayOrder.setActivityId(null); // 设置立减活动id
        String orderNo=StringUtils.generateOrdNo();
        newPayOrder.setOrderNo(orderNo);//订单号
        Station station = stationMapper.selectStationById(param.getStationId());
        newPayOrder.setEnterpriseId(param.getEnterpriseId());
        newPayOrder.setEnterpriseName(station==null?null:station.getEnterprise().getEnterpriseName());
        newPayOrder.setAppType(param.getAppType());
        //newPayOrder.setPayType(param.getPayType());
        newPayOrder.setPayType(PayTypeEnum.yhk.getType()); // 银行卡与pos机支付区分开
        newPayOrder.setOrderOriginType(param.getOrderOriginType());
        newPayOrder.setStationName(station.getStationName());
        newPayOrder.setStationId(station.getStationId());                  //油站id
        newPayOrder.setStatus("0");                                                //创建订单 未支付状态 0
        newPayOrder.setCreatedDate(new Date());           //创建时间
        newPayOrder.setOilGun(param.getOilGun());                        //油枪号
        newPayOrder.setDzkAmt(0d);             //电子卡金额
        newPayOrder.setOilPirce(param.getOilPirce()); //油价 原价
        newPayOrder.setOrderType(oilGun.getOil().getOilClass()); // 油品类
        newPayOrder.setOilName(oilGun.getOilId().toString()); // 油品id
        newPayOrder.setOrderLiters(param.getOrderLiters()); // 油升数
        newPayOrder.setOilPersonnelId(param.getOilPersonnelId());
        newPayOrder.setUtmSource("9");// 订单来源默认9
        newPayOrder.setXJStatus("1");//现金支付的状态（0申请1取消）
        if (userInfo != null) {
            newPayOrder.setCustomerPhone(userInfo.getMobilePhone());
            newPayOrder.setConsumerId(userInfo.getUserId());
            newPayOrder.setConsumer(userInfo.getBlogNickName());
        }
        PayOrderHandle.setPayOrderInvoiceStatus(newPayOrder);
        int i = payOrderMapper.insertSelectiveOrder(newPayOrder);  // 添加订单
        if (i<1) {
            throw new CustomException("创建订单失败");
        }

        //优惠金额
        BigDecimal discountAmt = null;
        //订单立减活动优惠
        if (param.getEnableDiscount()) {

            ReductionAndCouponDTO dto = reductionActivityService.calculateReductionDiscount(param, newPayOrder, station, oilGun, userInfo);
            if (dto != null && dto.getActivityId() != null) {
                //优惠金额
                discountAmt = dto.getReductionAmt();
                amt = amt.subtract(discountAmt);
                if (amt.compareTo(DecimalConstant.O_01)<0) {
                    amt = DecimalConstant.O_01;
                    discountAmt = originalAmt.subtract(DecimalConstant.O_01);
                }
                newPayOrder.setActivityId(dto.getActivityId());
                newPayOrder.setAmt(amt.doubleValue());
                newPayOrder.setDiscountAmt(discountAmt.doubleValue());
                newPayOrder.setConsumeDiscountAmt(discountAmt);
            }
        }
        // 计算渠道费
        PayWay payWayForm=new PayWay();
        payWayForm.setUseType(PayWayUseTypeEnum.CONSUME.getValue().toString());             //使用类型
        payWayForm.setStationId(param.getStationId());
        payWayForm.setAppType(PayWayServiceChargeEnum.APPTYPE_BANK_CARD.getValue().toString());
        PayWay payWay = payWayMapper.getOneStationPayWay(payWayForm); //获取该油站的支付类型
        if (payWay == null) {
            payWay = new PayWay();
        }
        calculatorChannelFee(newPayOrder,payWay,amt);
        newPayOrder.setPayWayId(payWay.getPayWayId());
        i = payOrderMapper.updateByPrimaryKeySelective(newPayOrder);
        if (i<1) {
            throw new CustomException("更新订单失败");
        }

		TradeReverseBankCardAddOrderVO vo =new TradeReverseBankCardAddOrderVO();
		vo.setIndustryId(tianQuetechIndustryId);
		vo.setOrderSn(newPayOrder.getOrderNo());
		vo.setProductId(tianQuetechProductId);
		vo.setAmt(BigDecimal.valueOf(newPayOrder.getAmt()));
		vo.setDiscountAmt(discountAmt == null ? BigDecimal.ZERO : discountAmt);
		return ResultData.successJson(vo);
	}

    private StaOilGun getOilGun(AddPayOrderParam param){
        //油品价格
        StaOilGun queryOilGun = new StaOilGun();
        queryOilGun.setGunName(param.getOilGun());    // 枪号
        queryOilGun.setStationId(param.getStationId());//油站id
        StaOilGun staOilGun = staOilGunMapper.selectStaGunInfo(queryOilGun);
        if(staOilGun == null){
            throw new CustomException("创建订单失败，未找到油枪信息");
        }
        return staOilGun;
    }
    private void calculatorChannelFee(PayOrder payOrder,PayWay payWay,BigDecimal amt){
        if (payWay.getServiceCharge() == null) {
            payOrder.setServiceCharge(BigDecimal.ZERO);
            payOrder.setCommission(0d);
            payOrder.setChannelFeePayer("1");
            payOrder.setActualAmt(amt);
            return;
        }
        payOrder.setChannelFeePayer(payWay.getChannelFeePayer());
        BigDecimal serviceCharge = payWay.getServiceCharge();
        payOrder.setServiceCharge(payWay.getServiceCharge());
        // 渠道费
        if(amt.compareTo(DecimalConstant.O_01)<=0){
            //金额小于等于0.01不计算渠道费
            payOrder.setCommission(0d);
            payOrder.setActualAmt(amt);
            return;
        }
        if (StringUtils.equals("1",payOrder.getChannelFeePayer())) {
            // 油企承担
            //渠道费
            BigDecimal commission = amt.multiply(serviceCharge).multiply(DecimalConstant.O_001).setScale(2, RoundingMode.HALF_UP);
            payOrder.setCommission(commission.doubleValue());
            payOrder.setActualAmt(amt);
        }else{
            // 司机承担
            // 司机承担的渠道费
            BigDecimal driverCommission = amt.multiply(serviceCharge).multiply(DecimalConstant.O_001).setScale(2, RoundingMode.HALF_UP);
            amt = amt.add(driverCommission).setScale(2,RoundingMode.HALF_UP);
            payOrder.setAmt(amt.doubleValue());
            payOrder.setActualAmt(amt);
            payOrder.setCommission(amt.multiply(serviceCharge).multiply(DecimalConstant.O_001).setScale(2,RoundingMode.HALF_UP).doubleValue());
        }
    }
    
	/**
	 * 银行刷卡支付更新订单
	 * @param param
	 */
	@Override
	public String bankCardUpdateOrder(BankCardUpdateOrderParam param) {
        if (StringUtils.equals("prod",profile)) {
            // 生产环境银行卡走统一回调，不走这里，下面代码是为测试环境
            return ResultData.successJson("成功");
        }
		PayOrder order=payOrderMapper.selectByOrdNo(param.getOrderSn());
		if(order==null) {
			logger.info("银行刷卡支付-订单不存在更新失败，订单号："+param.getOrderSn());
			return ResultData.errorJson("更新订单失败");
		}
        if (StringUtils.isNotBlank(order.getCustomerPhone())) {
            QuJiaPayV2Controller bean = SpringUtils.getBean(QuJiaPayV2Controller.class);
            String amt = String.valueOf(order.getAmt());
            String format = LocalDateUtils.format(LocalDateTime.now(), LocalDateUtils.DATETIME_FORMAT);
            bean.sxfPayOrderCallback(format,order.getOrderNo(), amt,null, amt, org.apache.commons.lang3.StringUtils.EMPTY, PayTypeEnum.yhk.getType());
            return ResultData.successJson("成功");
        }
		// TODO 4表示支付失败 需要优化
		if(order.getActivityId()!=null && !param.getStatus().equals("1")) {
			//支付失败的时候恢复预算
	        reductionActivityMapper.updateReductionActivityBudget(BigDecimal.valueOf(order.getDiscountAmt()), order.getActivityId().intValue());
		}
		
//		BigDecimal serviceCharge=order.getServiceCharge();
//		BigDecimal commission=serviceCharge.divide(new BigDecimal(1000)).multiply(new BigDecimal(order.getAmt())).setScale(2,BigDecimal.ROUND_UP);
//		BigDecimal receivedAmt= new BigDecimal(order.getAmt()).subtract(commission);
//		int type=updateTradeReverseOrder(param.getOrderSn(), param.getStatus(), serviceCharge,
//				commission.doubleValue(), param.getPayDate(), receivedAmt.doubleValue());
//		if(type<=0){
//			logger.info("订单更新失败，参数："+param.toString());
//			return ResultData.errorJson("更新订单失败");
//		}
        if (StringUtils.equals("1",param.getStatus())) {
            // status为1，支付成功，更新订单
            PayOrder updatePayOrder = new PayOrder();
            updatePayOrder.setOrderId(order.getOrderId());
            updatePayOrder.setStatus(param.getStatus());
            updatePayOrder.setPayDate(param.getPayDate());
            if (org.apache.commons.lang3.StringUtils.equals("0",order.getChannelFeePayer())) {
                // 司机承担渠道费
                Station station = stationMapper.selectStationById(order.getStationId());
                if (station != null && station.getIsShowSaasAmtCommission() == 0) {
                    // 后台订单列表不展示渠道费
                    BigDecimal recAmt = order.getReceivableAmt() == null ? BigDecimal.ZERO : BigDecimal.valueOf(order.getReceivableAmt());
                    BigDecimal disAmt = order.getDiscountAmt() == null ? BigDecimal.ZERO : BigDecimal.valueOf(order.getDiscountAmt());
                    BigDecimal couAmt = order.getDiscountCouponAmt() == null ? BigDecimal.ZERO : BigDecimal.valueOf(order.getDiscountCouponAmt());
                    BigDecimal amt = recAmt.subtract(disAmt).subtract(couAmt);
                    if (amt.compareTo(BigDecimal.ZERO)<=0) {
                        amt = DecimalConstant.O_01;
                    }
                    updatePayOrder.setAmt(amt.doubleValue());
                }
            }
            payOrderMapper.updateByPrimaryKeySelective(updatePayOrder);
        }else {
            logger.info("订单支付失败，参数:{}",param);
        }
		return ResultData.successJson("成功");
	}
	
	/**
	 * 订单参与立减活动进行金额优惠计算
	 * 1、pos机扫码 只能进行立减活动，所以不用考虑优惠券互斥、电子卡互斥等行为，不和用户进行关联，所以只要找到 当前油站id下的 油品id进行查询 
	 * 当前的时间段内是否存在某一种用途的活动.存在则获取这些活动，遍历活动，每次的活动进行计算 保留抵扣额度最大的活动，
	 * @param reductionActivitiesVO
	 */
	public BigDecimal reductionActivitiesAmountCalculation(ReductionActivitiesVO reductionActivitiesVO,String mobilePhone) {
        //计算当前是周几以及几号，查询时间是否符合
		BigDecimal finalDeductionAmount=BigDecimal.ZERO;//最后可以被扣除的金额
		logger.info("pos机开始进行立减，计算金额");
        Calendar calendar = Calendar.getInstance();
        int week = calendar.get(Calendar.DAY_OF_WEEK);
        int month = calendar.get(Calendar.DAY_OF_MONTH);
        if(week == 1){
            week = 7;
        }else{
            week--;
        }
		List<ReductionActivitiesAmountVO> acticity=reductionActivityMapper.selectReductionActivityStationId(reductionActivitiesVO);

            acticity=reductionActivityService.checkLabelUser2(acticity,mobilePhone);

		//当活动有且只有一个时，只需要查看是否适用于当前时间段
        ReductionActivity activity = new ReductionActivity();
        LocalTime nowTime = LocalTime.now();
        for(ReductionActivitiesAmountVO amoutv0:acticity) {

            activity.setTimeMode(amoutv0.getTimeMode());
            activity.setDays(amoutv0.getDays());
            activity.setWeeks(amoutv0.getWeeks());
            activity.setStartTimeOfWeek(amoutv0.getStartTimeOfWeek());
            activity.setEndTimeOfWeek(amoutv0.getEndTimeOfWeek());
            activity.setStartTimeOfMonth(amoutv0.getStartTimeOfMonth());
            activity.setEndTimeOfMonth(amoutv0.getEndTimeOfMonth());
            activity.setWeekTimeRangeType(amoutv0.getWeekTimeRangeType());
            activity.setMonthTimeRangeType(amoutv0.getMonthTimeRangeType());
            activity.setMemberCondition(amoutv0.getMemberCondition());
            activity.setPaymentMethod(amoutv0.getPaymentMethod());
            activity.setCardType(amoutv0.getCardType());
            activity.setPhysicalCardType(amoutv0.getPhysicalCardType());

            // 判断支付方式
            if (!reductionActivityService.checkActivityPayMethod(activity,
                    reductionActivitiesVO.getPaymentMethod(),
                    reductionActivitiesVO.getCardType(),
                    reductionActivitiesVO.getPhysicalCardOilType(),
                    reductionActivitiesVO.getPhysicalCardType())) {
                continue;
            }

            //判断实付金额是否超过上限门槛
            if(amoutv0.getAmtUpperLimit()!=null&&amoutv0.getAmtUpperLimit().compareTo(reductionActivitiesVO.getAmt())==-1){
                continue;
            }

            LocalDateTime modifyTime = LocalDateUtils.dateToLocalDateTime(amoutv0.getModifyTime());
            if(modifyTime.isBefore(ReductionActivityServiceImpl.OLD_ACTIVITY_CREATE_TIME)){
                //老活动逻辑
                //查看是否适用当前时间 生效时间段 all：全部时间段  week：按周选择 month：按月选择
                if(amoutv0.getTimeMode().equals("week") && amoutv0.getDays().contains(String.valueOf(week))) {
                    // 判断时间
                    if (!reductionActivityService.checkDayTime(activity, week, month, nowTime)) {
                        continue;
                    }
                    finalDeductionAmount=sumCountActivityMethods(amoutv0, finalDeductionAmount, reductionActivitiesVO);
                }else if(amoutv0.getTimeMode().equals("month") && amoutv0.getDays().contains(String.valueOf(month))) {
                    // 判断时间
                    if (!reductionActivityService.checkDayTime(activity, week, month, nowTime)) {
                        continue;
                    }
                    finalDeductionAmount=sumCountActivityMethods(amoutv0, finalDeductionAmount, reductionActivitiesVO);
                }else if (amoutv0.getTimeMode().equals("all") ){
                    //不是按周 按月，就一定是全部时间段生效
                    finalDeductionAmount=sumCountActivityMethods(amoutv0, finalDeductionAmount, reductionActivitiesVO);
                }
            }else{
                //新活动逻辑
                if("all".equals(amoutv0.getTimeMode())){
                    //全部时间
                    finalDeductionAmount = sumCountActivityMethods(amoutv0,finalDeductionAmount,reductionActivitiesVO);
                }else{
                    String days = amoutv0.getDays();
                    String weeks = amoutv0.getWeeks();
                    if(StringUtils.contains(days,String.valueOf(month)) || StringUtils.contains(weeks,String.valueOf(week))){
                        // 判断时间
                        if (!reductionActivityService.checkDayTime(activity, week, month, nowTime)) {
                            continue;
                        }
                        finalDeductionAmount = sumCountActivityMethods(amoutv0,finalDeductionAmount,reductionActivitiesVO);
                    }
                }
            }

		}
		logger.info("pos机进行立减，计算金额结束");
		return finalDeductionAmount;
	}
	
    /** 
     * 活动类型
     * AAL：每升立减
     * LOR：按固定数量
     * RFA：按固定金额 
     * 订单金额/油机价=升数，然后在对升数立减。支持阶梯????
     * 
     *  活动方式
     * RDD：随机立减
     * PAR：百分比立减
     * FAD：定额立减 
     * @param amoutv0
     * @param finalDeductionAmount
     * @param reductionActivitiesVO
     * @return
     */
	private BigDecimal sumCountActivityMethods(ReductionActivitiesAmountVO amoutv0,BigDecimal finalDeductionAmount,ReductionActivitiesVO reductionActivitiesVO) {
		ReductionRules reductionRules=new ReductionRules();
		List<ReductionRules> reductionList=new ArrayList<ReductionRules>();
		if(amoutv0.getOilPartOrAll() == 1) {
			//针对全部油品，规则直接关联活动
			reductionRules.setActivityId(amoutv0.getActivityId().longValue());
			reductionList=reductionRulesMapper.selectReductionRulesList(reductionRules);
		}else {
			//针对部分油品，规则关联油品
			reductionRules.setActivityOilId(new Long(amoutv0.getActivityOilId()));
			reductionList=reductionRulesMapper.selectReductionRulesList(reductionRules);
		}
		
		//对活动的具体内容开始计算，判断是哪种活动
		for(ReductionRules rules:reductionList) {
			BigDecimal amtBigd=BigDecimal.ZERO;		//临时金额
			BigDecimal orderLiters=BigDecimal.ZERO;	//加油的升数
			//活动类型
			switch (amoutv0.getActivityType()) {
                case Constant.REDUCTION_ACTIVITY_TYPE_LITRE_BY_LITRE:
                    logger.info("立减活动------每升立减-按升数");
                    finalDeductionAmount = calDiscountAmtByAALL(reductionList.get(0),rules, amoutv0, reductionActivitiesVO, finalDeductionAmount);
                    ReductionRules ruleAall = reductionList.get(0);
                    ruleAall.setActivityType(amoutv0.getActivityType());
                    ruleAall.setActivityMode(amoutv0.getActivityMode());
                    reductionActivitiesVO.setFRules(ruleAall);
                    break;
			case "AAL":
				logger.info("立减活动------每升立减");
				//每升立减 随机立减（满足x金额才能触发 每升立减活动 随机数在区间内进行随机）
				//每升立减 百分比立减
				//每升立减 定额立减
				finalDeductionAmount=countActivityMethods(reductionList.get(0),rules, amoutv0, reductionActivitiesVO, finalDeductionAmount);
                ReductionRules ruleAll = reductionList.get(0);
                ruleAll.setActivityType(amoutv0.getActivityType());
                ruleAll.setActivityMode(amoutv0.getActivityMode());
                reductionActivitiesVO.setFRules(ruleAll);
                break;
			case "LOR":
				//按固定数量 随机立减（满足x金额才能触发 每升立减活动 随机数在区间内进行随机）
				//按固定数量 百分比立减
				//按固定数量 定额立减
				logger.info("立减活动------固定数量");
				switch (amoutv0.getActivityMode()) {
				case "RDD":
					Double random = Math.random()*rules.getCutMax()+rules.getCutMin();//随机数
					if(random > rules.getCutMax()) random = rules.getCutMax();
					//满足多少升条件则 总共扣除金额=随机立减
					orderLiters=new BigDecimal(reductionActivitiesVO.getOrderLiters());
					if(orderLiters.compareTo(BigDecimal.valueOf(rules.getFull()))>=0) {
						amtBigd=BigDecimal.valueOf(random);
					}
					//判断是否超过了活动预算
					if(new BigDecimal(random).compareTo(amoutv0.getBudget())==1) {
						amtBigd=amoutv0.getBudget().compareTo(BigDecimal.ZERO)==1?amoutv0.getBudget():BigDecimal.ZERO;
					}
					if(finalDeductionAmount.compareTo(amtBigd)==-1) {
						finalDeductionAmount=amtBigd;
						reductionActivitiesVO.setActivityId(amoutv0.getActivityId().intValue());
					}
					break;
				case "PAR":
					//满足多少升条件则 总共扣除金额=原始金额*百分比
					orderLiters=new BigDecimal(reductionActivitiesVO.getOrderLiters());
					if(orderLiters.compareTo(BigDecimal.valueOf(rules.getFull()))>=0) {
						amtBigd=BigDecimal.valueOf(rules.getCut()).multiply(BigDecimal.valueOf(0.01)).multiply(reductionActivitiesVO.getAmt()) ;
					}
					if(finalDeductionAmount.compareTo(amtBigd)==-1) {
						finalDeductionAmount=amtBigd;
						reductionActivitiesVO.setActivityId(amoutv0.getActivityId().intValue());
					}
					break;
				case "FAD":
					//满足多少升条件则 总共扣除金额=固定金额
					orderLiters=new BigDecimal(reductionActivitiesVO.getOrderLiters());
					if(orderLiters.compareTo(BigDecimal.valueOf(rules.getFull()))>=0) {
						amtBigd=BigDecimal.valueOf(rules.getCut());
					}
					if(finalDeductionAmount.compareTo(amtBigd)==-1) {
						finalDeductionAmount=amtBigd;
						reductionActivitiesVO.setActivityId(amoutv0.getActivityId().intValue());
					}
					break;
				default:
					logger.info("LOR 没有找到活动方式");
					break;
				}
				break;
			case "RFA":
				logger.info("立减活动------固定金额");
				//按固定金额 随机立减（满足x金额才能触发 随机数在区间内进行随机）
				//按固定金额 百分比立减
				//按固定金额 定额立减
				amtBigd=BigDecimal.ZERO;
				orderLiters=BigDecimal.ZERO;
				switch (amoutv0.getActivityMode()) {
				case "RDD":
					logger.info("立减活动------随机立减");
					Double random = Math.random()*rules.getCutMax()+rules.getCutMin();//随机数
					if(random > rules.getCutMax()) random = rules.getCutMax();
					if(reductionActivitiesVO.getAmt().compareTo(BigDecimal.valueOf(rules.getFull()))>=0) {
						amtBigd=BigDecimal.valueOf(random);
					}
					//判断是否超过了活动预算
					if(new BigDecimal(random).compareTo(amoutv0.getBudget())==1) {
						amtBigd=amoutv0.getBudget().compareTo(BigDecimal.ZERO)==1?amoutv0.getBudget():BigDecimal.ZERO;
					}
					if(finalDeductionAmount.compareTo(amtBigd)==-1) {
						finalDeductionAmount=amtBigd;
						reductionActivitiesVO.setActivityId(amoutv0.getActivityId().intValue());
					}
					break;
				case "PAR":
					logger.info("立减活动------百分比立减");
					//满足达标金额 总共扣除金额=百分比*原始金额
					if(reductionActivitiesVO.getAmt().compareTo(BigDecimal.valueOf(rules.getFull()))>=0) {
						amtBigd=reductionActivitiesVO.getAmt().multiply(BigDecimal.valueOf(0.01)).multiply(BigDecimal.valueOf(rules.getCut()));
					}
					if(finalDeductionAmount.compareTo(amtBigd)==-1) {
						finalDeductionAmount=amtBigd;
						reductionActivitiesVO.setActivityId(amoutv0.getActivityId().intValue());
					}
					break;
				case "FAD":
					logger.info("立减活动------定额立减");
					//满足达标金额总共扣除金额=定额
					if(reductionActivitiesVO.getAmt().compareTo(BigDecimal.valueOf(rules.getFull()))>=0) {
						amtBigd=BigDecimal.valueOf(rules.getCut());
					}
					if(finalDeductionAmount.compareTo(amtBigd)==-1) {
						finalDeductionAmount=amtBigd;
						reductionActivitiesVO.setActivityId(amoutv0.getActivityId().intValue());
					}
					break;
				default:
					logger.info("RFA 没有找到活动方式");
					break;
				}
				break;
			default:
				logger.info("没有找到活动类型");
				break;
			}
		}
		return finalDeductionAmount;
	}


    /**
     * //每升立减-按升数 随机立减（满足x升数才能触发 每升立减活动 随机数在区间内进行随机）
     //每升立减 百分比立减
     //每升立减 定额立减
     * TODO 后续优化可使用设计模式
     * 计算活动方式能被抵扣的金额，获取最大抵扣额度
     * @param rules
     * @param amoutv0
     * @param reductionActivitiesVO
     * @param amtBig
     * @return
     */
    private BigDecimal calDiscountAmtByAALL(ReductionRules minRules,ReductionRules rules,ReductionActivitiesAmountVO amoutv0,
                                            ReductionActivitiesVO reductionActivitiesVO,BigDecimal amtBig) {
        BigDecimal amtBigd;
        BigDecimal liter = new BigDecimal(reductionActivitiesVO.getOrderLiters());
        switch (amoutv0.getActivityMode()) {
            // 随机立减暂时没有
//            case "RDD":
//                Double random = Math.random()*rules.getCutMax()+rules.getCutMin();//随机数
//                if(random > rules.getCutMax()) random = rules.getCutMax();
////			if(random < rules.getCutMin()) random = rules.getCutMin();
//                //每升立减活动（满足x金额才能触发 每升立减活动 随机数在区间内进行随机）
//                if(reductionActivitiesVO.getAmt().compareTo(BigDecimal.valueOf(rules.getFull()))>=0) {
//                    amtBigd=new BigDecimal(reductionActivitiesVO.getOrderLiters()).setScale(0, BigDecimal.ROUND_DOWN).multiply(BigDecimal.valueOf(random));
//                }
//
//                //判断是否超过了活动预算
//                if(new BigDecimal(random).compareTo(amoutv0.getBudget())==1) {
//                    amtBigd=amoutv0.getBudget().compareTo(BigDecimal.ZERO)==1?amoutv0.getBudget():BigDecimal.ZERO;
//                }
//
//                if(amtBig.compareTo(amtBigd)==-1) {
//                    amtBig=amtBigd;
//                    reductionActivitiesVO.setActivityId(amoutv0.getActivityId().intValue());
//                }
//                break;
            case "PAR":
                //总共扣除金额=百分比*单价
                //计算单价=总金额/总升
                if (rules.getFull() ==null || liter.compareTo(BigDecimal.valueOf(rules.getFull())) >= 0) {
                    amtBigd=reductionActivitiesVO.getAmt().multiply(BigDecimal.valueOf(rules.getCut())).multiply(DecimalConstant.O_01).setScale(2, RoundingMode.DOWN);
                    if(amtBig.compareTo(amtBigd) < 0) {
                        amtBig=amtBigd;
                        reductionActivitiesVO.setActivityId(amoutv0.getActivityId());
                    }
                    minRules.setCut(minRules.getCut() * minRules.getFull());
                }
                break;
            case "FAD":
                //总共扣除金额=每升*定额
                if (rules.getFull() ==null || liter.compareTo(BigDecimal.valueOf(rules.getFull())) >= 0) {
                    amtBigd= liter.multiply(BigDecimal.valueOf(rules.getCut()));
                    if(amtBig.compareTo(amtBigd) < 0) {
                        amtBig=amtBigd;
                        reductionActivitiesVO.setActivityId(amoutv0.getActivityId());
                    }
                }
                break;
            default:
                logger.info("AALL 未查询到活动方式");
                break;
        }
        return amtBig;
    }
	
	
	/**
	 * //每升立减 随机立减（满足x金额才能触发 每升立减活动 随机数在区间内进行随机）
				//每升立减 百分比立减
				//每升立减 定额立减
	 * TODO 后续优化可使用设计模式
	 * 计算活动方式能被抵扣的金额，获取最大抵扣额度
	 * @param rules
	 * @param amoutv0
	 * @param reductionActivitiesVO
	 * @param amtBig
	 * @return
	 */
	private BigDecimal countActivityMethods(ReductionRules minRules,ReductionRules rules,ReductionActivitiesAmountVO amoutv0,
			ReductionActivitiesVO reductionActivitiesVO,BigDecimal amtBig) {
		BigDecimal amtBigd=BigDecimal.ZERO;
		switch (amoutv0.getActivityMode()) {
		case "RDD":
			Double random = Math.random()*rules.getCutMax()+rules.getCutMin();//随机数
			if(random > rules.getCutMax()) random = rules.getCutMax();
//			if(random < rules.getCutMin()) random = rules.getCutMin();
			//每升立减活动（满足x金额才能触发 每升立减活动 随机数在区间内进行随机）
			if(reductionActivitiesVO.getAmt().compareTo(BigDecimal.valueOf(rules.getFull()))>=0) {
				amtBigd=new BigDecimal(reductionActivitiesVO.getOrderLiters()).setScale(0, BigDecimal.ROUND_DOWN).multiply(BigDecimal.valueOf(random));
			}
			
			//判断是否超过了活动预算
			if(new BigDecimal(random).compareTo(amoutv0.getBudget())==1) {
				amtBigd=amoutv0.getBudget().compareTo(BigDecimal.ZERO)==1?amoutv0.getBudget():BigDecimal.ZERO;
			}
			
			if(amtBig.compareTo(amtBigd)==-1) {
				amtBig=amtBigd;
				reductionActivitiesVO.setActivityId(amoutv0.getActivityId().intValue());
			}
			break;
		case "PAR":
			//总共扣除金额=百分比*单价
			//计算单价=总金额/总升
            if (rules.getFull() ==null || reductionActivitiesVO.getAmt().compareTo(BigDecimal.valueOf(rules.getFull())) >= 0) {
                amtBigd=reductionActivitiesVO.getAmt().multiply(BigDecimal.valueOf(rules.getCut())).multiply(BigDecimal.valueOf(0.01)).setScale(2, RoundingMode.DOWN);
                if(amtBig.compareTo(amtBigd)==-1) {
                    amtBig=amtBigd;
                    reductionActivitiesVO.setActivityId(amoutv0.getActivityId().intValue());
                    minRules.setCut(minRules.getCut() * minRules.getFull());
                }
            }
			break;
		case "FAD":
			//总共扣除金额=每升*定额
            if (rules.getFull() ==null || reductionActivitiesVO.getAmt().compareTo(BigDecimal.valueOf(rules.getFull())) >= 0) {
                amtBigd=new BigDecimal(reductionActivitiesVO.getOrderLiters()).multiply(BigDecimal.valueOf(rules.getCut()));
                if(amtBig.compareTo(amtBigd)==-1) {
                    amtBig=amtBigd;
                    reductionActivitiesVO.setActivityId(amoutv0.getActivityId().intValue());
                }
            }
			break;
		default:
			logger.info("AAL 未查询到活动方式");
			break;
		}
		return amtBig;
	}

	@Override
	public int updatePayOrder(PayOrder payOrder) {
		return payOrderMapper.updatePayOrder(payOrder);
	}

    @Override
    public int updatePayOrderInvoiceStatus(String orderNo, Integer invoiceStatus) {
        return payOrderMapper.updateInvoiceStatus(orderNo,invoiceStatus);
    }

    @Override
    public PayOrder posAddCarWashOrder(PayOrder payOrder) {
        PayOrderHandle.setPayOrderInvoiceStatus(payOrder);
        int insert = payOrderMapper.insertSelectiveOrder(payOrder);
        if (insert == 1){
            return payOrderMapper.selectOrderInfoByOrdNo(payOrder.getOrderNo());
        }
        return null;
    }

    @Override
    public int checkDzkRepeatPay(PayOrder payOrderInfo) {
        return payOrderMapper.checkDzkRepeatPay(payOrderInfo);
    }

    @Override
    public PayOrder getOneBetweenCreatedDateAndCreateDesc(PayOrder payOrder){
        return payOrderMapper.getOneBetweenCreatedDateAndCreateDesc(payOrder);
    }

    @Override
    public int updateGrowthValueByOrdNo(Long growthValue, String ordNo) {
        if(StringUtils.isNotEmpty(ordNo)){
            return payOrderMapper.updateGrowthValueByOrdNo(growthValue,ordNo);
        }
      return 0;
    }

    public int updateByPrimaryKeySelective(PayOrder payOrder){
        return payOrderMapper.updateByPrimaryKeySelective(payOrder);
    }

    @Override
    public List<PayOrder> selectPayOrderListFormater2(PayOrder payOrder) {
        return payOrderMapper.selectPayOrderListFormater2(payOrder);
    }

    @Override
    public List<PayOrder> selectPayOrderListFormater3(PayOrder payOrder) {
        return payOrderMapper.selectPayOrderListFormater3(payOrder);
    }

    @Override
    public int updatePayOrderInvoiceStatusByOrdNoAndBusinessName(String orderNo, Integer invoiceStatus, String businessName) {
        return payOrderMapper.updateInvoiceStatusByOrdNoAndBusinessName(orderNo,invoiceStatus, businessName);
    }

    @Override
    @Transactional
    public PayOrder createCashPayOrder(PayOrderRequest payOrderRequest){

        StaOilGun queryOilGun = new StaOilGun();
        queryOilGun.setGunName(payOrderRequest.getGunName());    // 枪号
        queryOilGun.setStationId(payOrderRequest.getStationId());//油站id
        StaOilGun oilGun = staOilGunMapper.selectStaGunInfo(queryOilGun);
        if(oilGun == null){
            throw new CustomException("创建订单失败，未找到油枪信息");
        }
        //订单实付金额
        BigDecimal amt = new BigDecimal(payOrderRequest.getReceivableAmt());
        AppUserInfo userInfo = null;
        if (payOrderRequest.getConsumerId() != null) {
            userInfo = appUserInfoService.getById(payOrderRequest.getConsumerId());
            if (userInfo == null) {
                throw new CustomException("会员未找到");
            }
        }
        Date now = new Date();
        PayOrder newPayOrder = new PayOrder();
        newPayOrder.setReceivableAmt(amt.doubleValue()); // 应收金额
        newPayOrder.setAmt(amt.doubleValue());// 实收金额
        newPayOrder.setDiscountAmt(0d);// 优惠金额
        newPayOrder.setConsumeDiscountAmt(BigDecimal.ZERO);
        newPayOrder.setRechargeDiscountAmt(BigDecimal.ZERO);
        newPayOrder.setActivityId(null); // 设置立减活动id
        String orderNo=StringUtils.generateOrdNo();
        newPayOrder.setOrderNo(orderNo);//订单号
        Station station = stationMapper.selectStationById(payOrderRequest.getStationId());
        newPayOrder.setEnterpriseId(station.getEnterpriseId());
        newPayOrder.setEnterpriseName(station==null?null:station.getEnterprise().getEnterpriseName());
        newPayOrder.setAppType(payOrderRequest.getAppType());
        newPayOrder.setPayType(PayTypeEnum.xj.getType());
        newPayOrder.setOrderOriginType(payOrderRequest.getOrderOriginType());
        newPayOrder.setStationName(station.getStationName());
        newPayOrder.setStationId(station.getStationId());                  //油站id
        newPayOrder.setCreatedDate(now);           //创建时间
        newPayOrder.setOilGun(payOrderRequest.getGunName());                        //油枪号
        newPayOrder.setDzkAmt(Double.valueOf(0));             //电子卡金额
        newPayOrder.setOilPirce(oilGun.getOilStationPrice().toString()); //油价 原价
        newPayOrder.setOrderType(oilGun.getOil().getOilClass()); // 油品类
        newPayOrder.setOilName(oilGun.getOilId().toString()); // 油品id
        BigDecimal oilLiters = new BigDecimal(payOrderRequest.getReceivableAmt()).divide(oilGun.getOilStationPrice(), 4, RoundingMode.HALF_UP);
        newPayOrder.setOrderLiters(oilLiters.toString()); // 油升数
        newPayOrder.setOilPersonnelId(payOrderRequest.getUserId());
        newPayOrder.setUtmSource("9");// 订单来源默认9
        newPayOrder.setXJStatus("1");//现金支付的状态（0申请1取消）
        newPayOrder.setStatus("1");
        newPayOrder.setConsumer("线下支付");       //客户昵称
        newPayOrder.setPayDate(now);
        if (userInfo != null) {
            newPayOrder.setStatus("0");
            newPayOrder.setPayDate(null);
            newPayOrder.setCustomerPhone(userInfo.getMobilePhone());
            newPayOrder.setConsumerId(userInfo.getUserId());
            newPayOrder.setConsumer(userInfo.getBlogNickName());
        }
        PayOrderHandle.setPayOrderInvoiceStatus(newPayOrder);
        int i = payOrderMapper.insertSelectiveOrder(newPayOrder);  // 添加订单
        if (i<1) {
            throw new CustomException("创建订单失败");
        }
        BigDecimal originalAmt = amt;
        //优惠金额
        BigDecimal discountAmt = null;
        if (payOrderRequest.getEnableDiscount() == null || payOrderRequest.getEnableDiscount()) {
            AddPayOrderParam orderParam = new AddPayOrderParam();
            orderParam.setAmt(payOrderRequest.getReceivableAmt());
            orderParam.setOrderLiters(newPayOrder.getOrderLiters());
            orderParam.setStationId(newPayOrder.getStationId());
            orderParam.setEnterpriseId(newPayOrder.getEnterpriseId());
            orderParam.setPayType(newPayOrder.getPayType());
            ReductionAndCouponDTO dto = reductionActivityService.calculateReductionDiscount(orderParam, newPayOrder, station, oilGun, userInfo);
            if (dto != null && dto.getActivityId() != null) {
                //优惠金额
                discountAmt = dto.getReductionAmt();
                amt = amt.subtract(discountAmt);
                if (amt.compareTo(DecimalConstant.O_01)<0) {
                    amt = DecimalConstant.O_01;
                    discountAmt = originalAmt.subtract(DecimalConstant.O_01);
                }
                newPayOrder.setActivityId(dto.getActivityId());
                newPayOrder.setAmt(amt.doubleValue());
                newPayOrder.setDiscountAmt(discountAmt.doubleValue());
                newPayOrder.setConsumeDiscountAmt(discountAmt);
            }
        }
        i = payOrderMapper.updateByPrimaryKeySelective(newPayOrder);
        if (i<1) {
            throw new CustomException("更新订单失败");
        }
        if (userInfo != null) {
            String amtStr = amt.toString();
            String timeStr = LocalDateTimeUtil.parse(now, LocalDateTimeUtil.YYYYMMDDHHMMSS);
            quJiaPayV2Controller.sxfPayOrderCallback(timeStr,newPayOrder.getOrderNo(), amtStr,null, amtStr,StringUtils.EMPTY,PayTypeEnum.xj.getType());
        }
        return selectOrderInfoByOrdNo(newPayOrder.getOrderNo());
    }

    @Override
    public PayOrder selectByOrdNo(String orderNo) {
        return payOrderMapper.selectByOrdNo(orderNo);
    }
}
